// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraAbilitySystemComponent.h"

// 包含必要的头文件
#include "AbilitySystem/Abilities/LyraGameplayAbility.h"
#include "AbilitySystem/LyraAbilityTagRelationshipMapping.h"
#include "Animation/LyraAnimInstance.h"
#include "Engine/World.h"
#include "GameFramework/Pawn.h"
#include "LyraGlobalAbilitySystem.h"
#include "LyraLogChannels.h"
#include "System/LyraAssetManager.h"
#include "System/LyraGameData.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraAbilitySystemComponent)

// 定义游戏标签 TAG_Gameplay_AbilityInputBlocked
UE_DEFINE_GAMEPLAY_TAG(TAG_Gameplay_AbilityInputBlocked, "Gameplay.AbilityInputBlocked");

// 构造函数
ULyraAbilitySystemComponent::ULyraAbilitySystemComponent(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
    // 重置输入相关的句柄数组
    InputPressedSpecHandles.Reset();
    InputReleasedSpecHandles.Reset();
    InputHeldSpecHandles.Reset();

    // 初始化激活组计数为0
    FMemory::Memset(ActivationGroupCounts, 0, sizeof(ActivationGroupCounts));
}

// 组件结束播放时的处理
void ULyraAbilitySystemComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
    // 从全局能力系统中注销
    if (ULyraGlobalAbilitySystem* GlobalAbilitySystem = UWorld::GetSubsystem<ULyraGlobalAbilitySystem>(GetWorld()))
    {
        GlobalAbilitySystem->UnregisterASC(this);
    }

    Super::EndPlay(EndPlayReason); // 调用父类实现
}

// 初始化能力执行者信息
void ULyraAbilitySystemComponent::InitAbilityActorInfo(AActor* InOwnerActor, AActor* InAvatarActor)
{
    FGameplayAbilityActorInfo* ActorInfo = AbilityActorInfo.Get();
    check(ActorInfo); // 确保ActorInfo有效
    check(InOwnerActor); // 确保所有者Actor有效

    // 检查是否有新的Pawn头像
    const bool bHasNewPawnAvatar = Cast<APawn>(InAvatarActor) && (InAvatarActor != ActorInfo->AvatarActor);

    // 调用父类实现
    Super::InitAbilityActorInfo(InOwnerActor, InAvatarActor);

    if (bHasNewPawnAvatar)
    {
        // 通知所有能力设置了新的Pawn头像
        for (const FGameplayAbilitySpec& AbilitySpec : ActivatableAbilities.Items)
        {
            ULyraGameplayAbility* LyraAbilityCDO = CastChecked<ULyraGameplayAbility>(AbilitySpec.Ability);

            // 处理实例化和非实例化能力
            if (LyraAbilityCDO->GetInstancingPolicy() != EGameplayAbilityInstancingPolicy::NonInstanced)
            {
                TArray<UGameplayAbility*> Instances = AbilitySpec.GetAbilityInstances();
                for (UGameplayAbility* AbilityInstance : Instances)
                {
                    ULyraGameplayAbility* LyraAbilityInstance = CastChecked<ULyraGameplayAbility>(AbilityInstance);
                    LyraAbilityInstance->OnPawnAvatarSet(); // 调用实例的OnPawnAvatarSet
                }
            }
            else
            {
                LyraAbilityCDO->OnPawnAvatarSet(); // 调用CDO的OnPawnAvatarSet
            }
        }

        // 注册到全局系统
        if (ULyraGlobalAbilitySystem* GlobalAbilitySystem = UWorld::GetSubsystem<ULyraGlobalAbilitySystem>(GetWorld()))
        {
            GlobalAbilitySystem->RegisterASC(this);
        }

        // 初始化动画实例
        if (ULyraAnimInstance* LyraAnimInst = Cast<ULyraAnimInstance>(ActorInfo->GetAnimInstance()))
        {
            LyraAnimInst->InitializeWithAbilitySystem(this);
        }

        // 尝试在生成时激活能力
        TryActivateAbilitiesOnSpawn();
    }
}

// 尝试在生成时激活能力
void ULyraAbilitySystemComponent::TryActivateAbilitiesOnSpawn()
{
    // 能力列表作用域锁
    ABILITYLIST_SCOPE_LOCK();
    for (const FGameplayAbilitySpec& AbilitySpec : ActivatableAbilities.Items)
    {
        const ULyraGameplayAbility* LyraAbilityCDO = CastChecked<ULyraGameplayAbility>(AbilitySpec.Ability);
        LyraAbilityCDO->TryActivateAbilityOnSpawn(AbilityActorInfo.Get(), AbilitySpec); // 尝试在生成时激活能力
    }
}

// 根据条件函数取消能力
void ULyraAbilitySystemComponent::CancelAbilitiesByFunc(TShouldCancelAbilityFunc ShouldCancelFunc, bool bReplicateCancelAbility)
{
    ABILITYLIST_SCOPE_LOCK();
    for (const FGameplayAbilitySpec& AbilitySpec : ActivatableAbilities.Items)
    {
        if (!AbilitySpec.IsActive()) // 跳过非激活状态的能力
        {
            continue;
        }

        ULyraGameplayAbility* LyraAbilityCDO = CastChecked<ULyraGameplayAbility>(AbilitySpec.Ability);

        // 处理实例化和非实例化能力
        if (LyraAbilityCDO->GetInstancingPolicy() != EGameplayAbilityInstancingPolicy::NonInstanced)
        {
            // 取消所有生成的实例，而不是CDO
            TArray<UGameplayAbility*> Instances = AbilitySpec.GetAbilityInstances();
            for (UGameplayAbility* AbilityInstance : Instances)
            {
                ULyraGameplayAbility* LyraAbilityInstance = CastChecked<ULyraGameplayAbility>(AbilityInstance);

                if (ShouldCancelFunc(LyraAbilityInstance, AbilitySpec.Handle)) // 检查是否应该取消
                {
                    if (LyraAbilityInstance->CanBeCanceled()) // 检查能力是否可取消
                    {
                        LyraAbilityInstance->CancelAbility(AbilitySpec.Handle, AbilityActorInfo.Get(), LyraAbilityInstance->GetCurrentActivationInfo(), bReplicateCancelAbility); // 取消能力实例
                    }
                    else
                    {
                        UE_LOG(LogLyraAbilitySystem, Error, TEXT("CancelAbilitiesByFunc: Can't cancel ability [%s] because CanBeCanceled is false."), *LyraAbilityInstance->GetName()); // 记录错误日志
                    }
                }
            }
        }
        else
        {
            // 取消非实例化能力CDO
            if (ShouldCancelFunc(LyraAbilityCDO, AbilitySpec.Handle)) // 检查是否应该取消
            {
                // 非实例化能力总是可以取消
                check(LyraAbilityCDO->CanBeCanceled()); // 确保能力可取消
                LyraAbilityCDO->CancelAbility(AbilitySpec.Handle, AbilityActorInfo.Get(), FGameplayAbilityActivationInfo(), bReplicateCancelAbility); // 取消能力CDO
            }
        }
    }
}

// 取消输入激活的能力
void ULyraAbilitySystemComponent::CancelInputActivatedAbilities(bool bReplicateCancelAbility)
{
    // 定义取消条件：输入触发或输入保持激活的能力
    auto ShouldCancelFunc = [this](const ULyraGameplayAbility* LyraAbility, FGameplayAbilitySpecHandle Handle)
    {
        const ELyraAbilityActivationPolicy ActivationPolicy = LyraAbility->GetActivationPolicy();
        return ((ActivationPolicy == ELyraAbilityActivationPolicy::OnInputTriggered) || (ActivationPolicy == ELyraAbilityActivationPolicy::WhileInputActive)); // 返回是否应该取消
    };

    CancelAbilitiesByFunc(ShouldCancelFunc, bReplicateCancelAbility); // 调用取消函数
}

// 能力输入按下处理
void ULyraAbilitySystemComponent::AbilitySpecInputPressed(FGameplayAbilitySpec& Spec)
{
    Super::AbilitySpecInputPressed(Spec); // 调用父类实现

    // 不支持 UGameplayAbility::bReplicateInputDirectly
    // 使用复制事件代替，以便 WaitInputPress 能力任务工作
    if (Spec.IsActive()) // 检查能力是否激活
    {
        // 调用 InputPressed 事件，这里不复制
        InvokeReplicatedEvent(EAbilityGenericReplicatedEvent::InputPressed, Spec.Handle, Spec.ActivationInfo.GetActivationPredictionKey()); // 调用复制事件
    }
}

// 能力输入释放处理
void ULyraAbilitySystemComponent::AbilitySpecInputReleased(FGameplayAbilitySpec& Spec)
{
    Super::AbilitySpecInputReleased(Spec); // 调用父类实现

    // 不支持 UGameplayAbility::bReplicateInputDirectly
    // 使用复制事件代替，以便 WaitInputRelease 能力任务工作
    if (Spec.IsActive()) // 检查能力是否激活
    {
        // 调用 InputReleased 事件，这里不复制
        InvokeReplicatedEvent(EAbilityGenericReplicatedEvent::InputReleased, Spec.Handle, Spec.ActivationInfo.GetActivationPredictionKey()); // 调用复制事件
    }
}

// 输入标签按下处理
void ULyraAbilitySystemComponent::AbilityInputTagPressed(const FGameplayTag& InputTag)
{
    if (InputTag.IsValid()) // 检查输入标签是否有效
    {
        // 遍历所有可激活能力，找到匹配输入标签的
        for (const FGameplayAbilitySpec& AbilitySpec : ActivatableAbilities.Items)
        {
            if (AbilitySpec.Ability && (AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag))) // 检查能力是否存在且标签匹配
            {
                InputPressedSpecHandles.AddUnique(AbilitySpec.Handle); // 添加到按下句柄列表
                InputHeldSpecHandles.AddUnique(AbilitySpec.Handle); // 添加到保持句柄列表
            }
        }
    }
}

// 输入标签释放处理
void ULyraAbilitySystemComponent::AbilityInputTagReleased(const FGameplayTag& InputTag)
{
    if (InputTag.IsValid()) // 检查输入标签是否有效
    {
        // 遍历所有可激活能力，找到匹配输入标签的
        for (const FGameplayAbilitySpec& AbilitySpec : ActivatableAbilities.Items)
        {
            if (AbilitySpec.Ability && (AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag))) // 检查能力是否存在且标签匹配
            {
                InputReleasedSpecHandles.AddUnique(AbilitySpec.Handle); // 添加到释放句柄列表
                InputHeldSpecHandles.Remove(AbilitySpec.Handle); // 从保持句柄列表移除
            }
        }
    }
}

// 处理能力输入
void ULyraAbilitySystemComponent::ProcessAbilityInput(float DeltaTime, bool bGamePaused)
{
    // 如果能力输入被阻塞，清空输入
    if (HasMatchingGameplayTag(TAG_Gameplay_AbilityInputBlocked)) // 检查是否有输入阻塞标签
    {
        ClearAbilityInput(); // 清空输入
        return;
    }

    static TArray<FGameplayAbilitySpecHandle> AbilitiesToActivate;
    AbilitiesToActivate.Reset(); // 重置激活列表

    // 处理输入保持激活的能力
    for (const FGameplayAbilitySpecHandle& SpecHandle : InputHeldSpecHandles)
    {
        if (const FGameplayAbilitySpec* AbilitySpec = FindAbilitySpecFromHandle(SpecHandle)) // 查找能力规格
        {
            if (AbilitySpec->Ability && !AbilitySpec->IsActive()) // 检查能力存在且未激活
            {
                const ULyraGameplayAbility* LyraAbilityCDO = CastChecked<ULyraGameplayAbility>(AbilitySpec->Ability);

                if (LyraAbilityCDO->GetActivationPolicy() == ELyraAbilityActivationPolicy::WhileInputActive) // 检查激活策略
                {
                    AbilitiesToActivate.AddUnique(AbilitySpec->Handle); // 添加到激活列表
                }
            }
        }
    }

    // 处理输入按下的能力
    for (const FGameplayAbilitySpecHandle& SpecHandle : InputPressedSpecHandles)
    {
        if (FGameplayAbilitySpec* AbilitySpec = FindAbilitySpecFromHandle(SpecHandle)) // 查找能力规格
        {
            if (AbilitySpec->Ability)
            {
                AbilitySpec->InputPressed = true; // 设置输入按下标志

                if (AbilitySpec->IsActive()) // 检查能力是否已激活
                {
                    // 能力已激活，传递输入事件
                    AbilitySpecInputPressed(*AbilitySpec); // 调用输入按下处理
                }
                else
                {
                    const ULyraGameplayAbility* LyraAbilityCDO = CastChecked<ULyraGameplayAbility>(AbilitySpec->Ability);

                    if (LyraAbilityCDO->GetActivationPolicy() == ELyraAbilityActivationPolicy::OnInputTriggered) // 检查激活策略
                    {
                        AbilitiesToActivate.AddUnique(AbilitySpec->Handle); // 添加到激活列表
                    }
                }
            }
        }
    }

    // 尝试激活所有按下和保持输入的能力
    for (const FGameplayAbilitySpecHandle& AbilitySpecHandle : AbilitiesToActivate)
    {
        TryActivateAbility(AbilitySpecHandle); // 尝试激活能力
    }

    // 处理输入释放的能力
    for (const FGameplayAbilitySpecHandle& SpecHandle : InputReleasedSpecHandles)
    {
        if (FGameplayAbilitySpec* AbilitySpec = FindAbilitySpecFromHandle(SpecHandle)) // 查找能力规格
        {
            if (AbilitySpec->Ability)
            {
                AbilitySpec->InputPressed = false; // 设置输入按下标志为false

                if (AbilitySpec->IsActive()) // 检查能力是否已激活
                {
                    // 能力已激活，传递输入事件
                    AbilitySpecInputReleased(*AbilitySpec); // 调用输入释放处理
                }
            }
        }
    }

    // 清空缓存的输入句柄
    InputPressedSpecHandles.Reset(); // 重置按下句柄列表
    InputReleasedSpecHandles.Reset(); // 重置释放句柄列表
}

// 清空能力输入
void ULyraAbilitySystemComponent::ClearAbilityInput()
{
    InputPressedSpecHandles.Reset(); // 重置按下句柄列表
    InputReleasedSpecHandles.Reset(); // 重置释放句柄列表
    InputHeldSpecHandles.Reset(); // 重置保持句柄列表
}

// 通知能力激活
void ULyraAbilitySystemComponent::NotifyAbilityActivated(const FGameplayAbilitySpecHandle Handle, UGameplayAbility* Ability)
{
    Super::NotifyAbilityActivated(Handle, Ability); // 调用父类实现

    ULyraGameplayAbility* LyraAbility = CastChecked<ULyraGameplayAbility>(Ability);

    // 添加能力到激活组
    AddAbilityToActivationGroup(LyraAbility->GetActivationGroup(), LyraAbility); // 添加到激活组
}

// 通知能力激活失败
void ULyraAbilitySystemComponent::NotifyAbilityFailed(const FGameplayAbilitySpecHandle Handle, UGameplayAbility* Ability, const FGameplayTagContainer& FailureReason)
{
    Super::NotifyAbilityFailed(Handle, Ability, FailureReason); // 调用父类实现

    // 如果是非本地控制的Pawn且能力支持网络，通知客户端
    if (APawn* Avatar = Cast<APawn>(GetAvatarActor())) // 获取头像Pawn
    {
        if (!Avatar->IsLocallyControlled() && Ability->IsSupportedForNetworking()) // 检查是否非本地控制且支持网络
        {
            ClientNotifyAbilityFailed(Ability, FailureReason); // 通知客户端
            return;
        }
    }

    HandleAbilityFailed(Ability, FailureReason); // 处理能力失败
}

// 通知能力结束
void ULyraAbilitySystemComponent::NotifyAbilityEnded(FGameplayAbilitySpecHandle Handle, UGameplayAbility* Ability, bool bWasCancelled)
{
    Super::NotifyAbilityEnded(Handle, Ability, bWasCancelled); // 调用父类实现

    ULyraGameplayAbility* LyraAbility = CastChecked<ULyraGameplayAbility>(Ability);

    // 从激活组移除能力
    RemoveAbilityFromActivationGroup(LyraAbility->GetActivationGroup(), LyraAbility); // 从激活组移除
}

// 应用能力阻塞和取消标签
void ULyraAbilitySystemComponent::ApplyAbilityBlockAndCancelTags(const FGameplayTagContainer& AbilityTags, UGameplayAbility* RequestingAbility, bool bEnableBlockTags, const FGameplayTagContainer& BlockTags, bool bExecuteCancelTags, const FGameplayTagContainer& CancelTags)
{
    FGameplayTagContainer ModifiedBlockTags = BlockTags;
    FGameplayTagContainer ModifiedCancelTags = CancelTags;

    // 使用标签关系映射扩展能力标签
    if (TagRelationshipMapping) // 检查标签关系映射是否存在
    {
        TagRelationshipMapping->GetAbilityTagsToBlockAndCancel(AbilityTags, &ModifiedBlockTags, &ModifiedCancelTags); // 获取阻塞和取消标签
    }

    Super::ApplyAbilityBlockAndCancelTags(AbilityTags, RequestingAbility, bEnableBlockTags, ModifiedBlockTags, bExecuteCancelTags, ModifiedCancelTags); // 调用父类实现

    // 待办：应用特殊逻辑，如阻塞输入或移动
}

// 处理能力可取消状态变化
void ULyraAbilitySystemComponent::HandleChangeAbilityCanBeCanceled(const FGameplayTagContainer& AbilityTags, UGameplayAbility* RequestingAbility, bool bCanBeCanceled)
{
    Super::HandleChangeAbilityCanBeCanceled(AbilityTags, RequestingAbility, bCanBeCanceled); // 调用父类实现

    // 待办：应用特殊逻辑，如阻塞输入或移动
}

// 获取额外的激活标签需求
void ULyraAbilitySystemComponent::GetAdditionalActivationTagRequirements(const FGameplayTagContainer& AbilityTags, FGameplayTagContainer& OutActivationRequired, FGameplayTagContainer& OutActivationBlocked) const
{
    if (TagRelationshipMapping) // 检查标签关系映射是否存在
    {
        TagRelationshipMapping->GetRequiredAndBlockedActivationTags(AbilityTags, &OutActivationRequired, &OutActivationBlocked); // 获取需求和阻塞标签
    }
}

// 设置标签关系映射
void ULyraAbilitySystemComponent::SetTagRelationshipMapping(ULyraAbilityTagRelationshipMapping* NewMapping)
{
    TagRelationshipMapping = NewMapping; // 设置新的标签关系映射
}

// 客户端通知能力失败（RPC）
void ULyraAbilitySystemComponent::ClientNotifyAbilityFailed_Implementation(const UGameplayAbility* Ability, const FGameplayTagContainer& FailureReason)
{
    HandleAbilityFailed(Ability, FailureReason); // 处理能力失败
}

// 处理能力失败
void ULyraAbilitySystemComponent::HandleAbilityFailed(const UGameplayAbility* Ability, const FGameplayTagContainer& FailureReason)
{
    // 记录能力失败日志
    //UE_LOG(LogLyraAbilitySystem, Warning, TEXT("Ability %s failed to activate (tags: %s)"), *GetPathNameSafe(Ability), *FailureReason.ToString());

    // 调用能力的失败回调
    if (const ULyraGameplayAbility* LyraAbility = Cast<const ULyraGameplayAbility>(Ability)) // 转换为Lyra能力
    {
        LyraAbility->OnAbilityFailedToActivate(FailureReason); // 调用能力失败回调
    }    
}

// 检查激活组是否被阻塞
bool ULyraAbilitySystemComponent::IsActivationGroupBlocked(ELyraAbilityActivationGroup Group) const
{
    bool bBlocked = false;

    switch (Group)
    {
    case ELyraAbilityActivationGroup::Independent:
        // 独立能力永远不会被阻塞
        bBlocked = false; // 独立能力不阻塞
        break;

    case ELyraAbilityActivationGroup::Exclusive_Replaceable:
    case ELyraAbilityActivationGroup::Exclusive_Blocking:
        // 如果没有阻塞，独占能力可以激活
        bBlocked = (ActivationGroupCounts[(uint8)ELyraAbilityActivationGroup::Exclusive_Blocking] > 0); // 检查是否有阻塞能力
        break;

    default:
        checkf(false, TEXT("IsActivationGroupBlocked: Invalid ActivationGroup [%d]\n"), (uint8)Group); // 无效激活组错误
        break;
    }

    return bBlocked; // 返回阻塞状态
}

// 添加能力到激活组
void ULyraAbilitySystemComponent::AddAbilityToActivationGroup(ELyraAbilityActivationGroup Group, ULyraGameplayAbility* LyraAbility)
{
    check(LyraAbility); // 确保能力有效
    check(ActivationGroupCounts[(uint8)Group] < INT32_MAX); // 确保计数不会溢出

    // 增加组计数
    ActivationGroupCounts[(uint8)Group]++; // 增加激活组计数

    const bool bReplicateCancelAbility = false; // 设置不复制取消

    switch (Group)
    {
    case ELyraAbilityActivationGroup::Independent:
        // 独立能力不取消任何其他能力
        break;

    case ELyraAbilityActivationGroup::Exclusive_Replaceable:
    case ELyraAbilityActivationGroup::Exclusive_Blocking:
        // 取消可替换的独占能力
        CancelActivationGroupAbilities(ELyraAbilityActivationGroup::Exclusive_Replaceable, LyraAbility, bReplicateCancelAbility); // 取消可替换能力
        break;

    default:
        checkf(false, TEXT("AddAbilityToActivationGroup: Invalid ActivationGroup [%d]\n"), (uint8)Group); // 无效激活组错误
        break;
    }

    // 确保只有一个独占能力在运行
    const int32 ExclusiveCount = ActivationGroupCounts[(uint8)ELyraAbilityActivationGroup::Exclusive_Replaceable] + ActivationGroupCounts[(uint8)ELyraAbilityActivationGroup::Exclusive_Blocking]; // 计算独占能力总数
    if (!ensure(ExclusiveCount <= 1)) // 确保不超过一个独占能力
    {
        UE_LOG(LogLyraAbilitySystem, Error, TEXT("AddAbilityToActivationGroup: Multiple exclusive abilities are running.")); // 记录错误日志
    }
}

// 从激活组移除能力
void ULyraAbilitySystemComponent::RemoveAbilityFromActivationGroup(ELyraAbilityActivationGroup Group, ULyraGameplayAbility* LyraAbility)
{
    check(LyraAbility); // 确保能力有效
    check(ActivationGroupCounts[(uint8)Group] > 0); // 确保计数大于0

    // 减少组计数
    ActivationGroupCounts[(uint8)Group]--; // 减少激活组计数
}

// 取消激活组中的能力
void ULyraAbilitySystemComponent::CancelActivationGroupAbilities(ELyraAbilityActivationGroup Group, ULyraGameplayAbility* IgnoreLyraAbility, bool bReplicateCancelAbility)
{
    // 定义取消条件：指定组中且不是忽略的能力
    auto ShouldCancelFunc = [this, Group, IgnoreLyraAbility](const ULyraGameplayAbility* LyraAbility, FGameplayAbilitySpecHandle Handle)
    {
        return ((LyraAbility->GetActivationGroup() == Group) && (LyraAbility != IgnoreLyraAbility)); // 返回是否应该取消
    };

    CancelAbilitiesByFunc(ShouldCancelFunc, bReplicateCancelAbility); // 调用取消函数
}

// 添加动态标签游戏效果
void ULyraAbilitySystemComponent::AddDynamicTagGameplayEffect(const FGameplayTag& Tag)
{
    // 获取动态标签游戏效果类
    const TSubclassOf<UGameplayEffect> DynamicTagGE = ULyraAssetManager::GetSubclass(ULyraGameData::Get().DynamicTagGameplayEffect); // 获取游戏效果类
    if (!DynamicTagGE) // 检查游戏效果类是否存在
    {
        UE_LOG(LogLyraAbilitySystem, Warning, TEXT("AddDynamicTagGameplayEffect: Unable to find DynamicTagGameplayEffect [%s]."), *ULyraGameData::Get().DynamicTagGameplayEffect.GetAssetName()); // 记录警告日志
        return;
    }

    // 创建游戏效果规格
    const FGameplayEffectSpecHandle SpecHandle = MakeOutgoingSpec(DynamicTagGE, 1.0f, MakeEffectContext()); // 创建效果规格
    FGameplayEffectSpec* Spec = SpecHandle.Data.Get(); // 获取效果规格指针

    if (!Spec) // 检查效果规格是否存在
    {
        UE_LOG(LogLyraAbilitySystem, Warning, TEXT("AddDynamicTagGameplayEffect: Unable to make outgoing spec for [%s]."), *GetNameSafe(DynamicTagGE)); // 记录警告日志
        return;
    }

    // 添加动态授予标签
    Spec->DynamicGrantedTags.AddTag(Tag); // 添加动态标签

    // 应用游戏效果到自身
    ApplyGameplayEffectSpecToSelf(*Spec); // 应用效果到自身
}

// 移除动态标签游戏效果
void ULyraAbilitySystemComponent::RemoveDynamicTagGameplayEffect(const FGameplayTag& Tag)
{
    // 获取动态标签游戏效果类
    const TSubclassOf<UGameplayEffect> DynamicTagGE = ULyraAssetManager::GetSubclass(ULyraGameData::Get().DynamicTagGameplayEffect); // 获取游戏效果类
    if (!DynamicTagGE) // 检查游戏效果类是否存在
    {
        UE_LOG(LogLyraAbilitySystem, Warning, TEXT("RemoveDynamicTagGameplayEffect: Unable to find gameplay effect [%s]."), *ULyraGameData::Get().DynamicTagGameplayEffect.GetAssetName()); // 记录警告日志
        return;
    }

    // 创建查询并移除活动效果
    FGameplayEffectQuery Query = FGameplayEffectQuery::MakeQuery_MatchAnyOwningTags(FGameplayTagContainer(Tag)); // 创建标签查询
    Query.EffectDefinition = DynamicTagGE; // 设置效果定义

    RemoveActiveEffects(Query); // 移除活动效果
}

// 获取能力目标数据
void ULyraAbilitySystemComponent::GetAbilityTargetData(const FGameplayAbilitySpecHandle AbilityHandle, FGameplayAbilityActivationInfo ActivationInfo, FGameplayAbilityTargetDataHandle& OutTargetDataHandle)
{
    // 从能力目标数据映射中查找数据
    TSharedPtr<FAbilityReplicatedDataCache> ReplicatedData = AbilityTargetDataMap.Find(FGameplayAbilitySpecHandleAndPredictionKey(AbilityHandle, ActivationInfo.GetActivationPredictionKey())); // 查找复制数据
    if (ReplicatedData.IsValid()) // 检查数据是否有效
    {
        OutTargetDataHandle = ReplicatedData->TargetData; // 设置输出目标数据
    }
}